package com.ctgu.B.B2;

import com.ctgu.B.B2.action.*;
import com.ctgu.B.B2.condition.PasswordCondition;
import com.github.oxo42.stateless4j.StateMachine;
import com.github.oxo42.stateless4j.StateMachineConfig;

/**
 * 密码验证器
 */
public class ControlPanel {

    private StateMachineConfig<State, Event> config;
    private StateMachine<State, Event> stateMachine;
    private PasswordCondition passwordCondition = new PasswordCondition();

    public ControlPanel() {
        init();
    }

    public void init() {
        // 创建状态机配置
        config = new StateMachineConfig<>();

//        inputCharacter
//        submitPassword
//        passwordValid
//        passwordInvalid
//        lock
//        lockTimeout

        // 等待状态
        //1. 等待状态转为读取键入字符状态
        config.configure(State.STANDBY)
                .permit(Event.inputCharacter, State.INPUT_PASSWORD,new InputCharAction())
                .ignore(Event.passwordValid)
                .ignore(Event.passwordInvalid)
                .ignore(Event.lock)
                .ignore(Event.lockTimeout);

        // 读取键入字符状态
        //1. 读取键入字符状态保持不变
        //2. 读取键入字符状态转为验证密码状态，当密码条件满足时
        config.configure(State.INPUT_PASSWORD)
                .ignoreIf(Event.inputCharacter, passwordCondition.isNotMeetTheConditions())
                .permitIf(Event.inputCharacter, State.VALIDATING_PASSWORD,passwordCondition.isMeetTheConditions(),new SubmitPasswordAction())
                .ignore(Event.passwordValid)
                .ignore(Event.passwordInvalid)
                .ignore(Event.lock)
                .ignore(Event.lockTimeout);

        // 验证密码状态
        //1. 验证密码成功状态转为系统功能选择状态
        //2. 验证密码失败三次转为锁定状态
        //3. 验证密码失败状态转为重新输入密码状态
        config.configure(State.VALIDATING_PASSWORD)
                .permit(Event.passwordValid, State.SYSTEM_FUNCTION_SELECTION, new ToSystemFunctionSelectionAction())
                .permitIf(Event.passwordInvalid, State.LOCKED, passwordCondition.isLock(),new LockAction())
                .permitIf(Event.passwordInvalid, State.INPUT_PASSWORD,passwordCondition.isNotLock(),new ReturnInputPasswordAction())
                .ignore(Event.inputCharacter)
                .ignore(Event.lock)
                .ignore(Event.lockTimeout);

        // 锁定状态
        //1. 锁定状态转为重新输入密码状态
        config.configure(State.LOCKED)
                .permit(Event.lockTimeout, State.INPUT_PASSWORD, new UnlockAction())
                .ignore(Event.inputCharacter)
                .ignore(Event.passwordValid)
                .ignore(Event.passwordInvalid)
                .ignore(Event.lock);

        // 创建状态机实例，初始状态为输入密码状态
        stateMachine = new StateMachine<>(State.STANDBY, config);
    }

    public void fire(Event event) {
        this.stateMachine.fire(event);
    }

    public State getCurrentState() {
        return this.stateMachine.getState();
    }

    public void printCurrentState() {
        System.out.println("Current State: " + stateMachine.getState());
    }

}
